package com.gpframework.exception;

import com.gpframework.common.constant.HttpStatus;
import com.gpframework.common.core.domain.AjaxResult;
import com.gpframework.common.exception.*;
import com.gpframework.common.utils.MessageUtils;
import com.gpframework.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * 全局异常处理器
 *
 * @Author gpframework
 */
@RestControllerAdvice
@SuppressWarnings({"rawtypes"})
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 基础异常
     */
    @ExceptionHandler(BaseException.class)
    public AjaxResult baseException(BaseException e) {
        log.error("baseException:{}", e.getDefaultMessage());
        if ("user.jcaptcha.expire".equals(e.getCode()) || "user.jcaptcha.error".equals(e.getCode()) || "user.password.not.match".equals(e.getCode())) {
            return AjaxResult.error(MessageUtils.message(e.getCode()));
        }
        return AjaxResult.error("Base Exception");
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(CustomException.class)
    public AjaxResult businessException(CustomException e) {
        log.error("businessException:{}", e);
        if (StringUtils.isNull(e.getCode())) {
            return AjaxResult.error("Business Exception");
        }
        return AjaxResult.error(e.getCode(), "Business Exception");
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public AjaxResult handlerNoFoundException(Exception e) {
        log.error("handlerNoFoundException:{}", e);
        return AjaxResult.error(HttpStatus.NOT_FOUND, "The path does not exist, please check whether the path is correct");
    }

    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAuthorizationException(AccessDeniedException e) {
        log.error("handleAuthorizationException:{}", e);
        return AjaxResult.error(HttpStatus.FORBIDDEN, "No permission, please contact the administrator for authorization");
    }

    @ExceptionHandler(AccountExpiredException.class)
    public AjaxResult handleAccountExpiredException(AccountExpiredException e) {
        log.error("handleAccountExpiredException:{}", e);
        return AjaxResult.error("Account Expires");
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e) {
        log.error("handleUsernameNotFoundException:{}", e);
        return AjaxResult.error("Username Not Found");
    }

    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e) {
        log.error("handleException:{}", e);
        return AjaxResult.error("Handle Exception");
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult validatedBindException(BindException e) {
        String message = e.getAllErrors().get(0).getDefaultMessage();
        log.error("validatedBindException:{}", e);
        return AjaxResult.error(HttpStatus.BAD_REQUEST, "Validated Bind Exception");
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object validExceptionHandler(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        log.error("validExceptionHandler:{}", e);
        return AjaxResult.error(HttpStatus.BAD_REQUEST, "Valid Exception");
    }

    /**
     * 参数异常
     */
    @ExceptionHandler(ParamException.class)
    public Object paramExceptionHandler(ParamException e) {
        String message = e.getMessage();
        log.error("paramExceptionHandler:{}", e);
        return AjaxResult.error(HttpStatus.BAD_REQUEST, "Param Exception");
    }

    /**
     * 数据不存在异常
     */
    @ExceptionHandler(DataNotFoundException.class)
    public Object dataNotFoundExceptionHandler(DataNotFoundException e) {
        String message = e.getMessage();
        log.error("dataNotFoundExceptionHandler:{}", e);
        return AjaxResult.error(HttpStatus.NOT_FOUND, "Data Not Found");
    }

    /**
     * 数据不存在异常
     */
    @ExceptionHandler(DataExistException.class)
    public Object dataExistExceptionHandler(DataExistException e) {
        String message = e.getMessage();
        log.error("dataExistExceptionHandler:{}", e);
        return AjaxResult.error(HttpStatus.CONFLICT, "Data Exception");
    }

    /**
     * 演示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
    public AjaxResult demoModeException(DemoModeException e) {
        log.error("demoModeException:{}", e);
        return AjaxResult.error("Demo mode, operation not allowed");
    }
}
